package aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

/**
 * Service层AOP切面配置
 * @author huangqiankun
 * @date 2020年5月13日下午5:45:49
 */
//@Slf4j
//@Aspect
//@Component
public class ServiceAspect {

	/**
     * <p>通过@Pointcut注解声明频繁使用的切点表达式</p>
     * <p>execution(public * com.baomidou.mybatisplus.extension.service.IService+.*(..)))	execution表达式方式</p>
     * <p>@annotation(xxx.xxx.xxx.xxx)	注解方式(该方式只能切入方法上的注解，如果要切入类上的注解 需要使用 @within)</p>
     * <p>@within(xxx.xxx.xxx.xxx)	注解方式(该方式可以切入类上的注解)</p>
     * <p>bean(*Service)	bean方式</p>
     * <p>within(com.baomidou.mybatisplus.extension.service.*Service)	匹配class方式</p>
     */
	@Pointcut("within(com.baomidou.mybatisplus.extension.service.IService+) && (execution(* save*(..)) || execution(* update*(..)))")
	public void aspect() {};


    /**
     * <p>环绕连接点的方法 可以判断最终是否执行连接点<p>
     */
    @Around("aspect()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    	/*
    	 * 连接点前执行代码块
    	 */

    	/*
    	 * 如果不想执行连接点 就不要调用 proceedingJoinPoint.proceed() 执行连接点
    	 */
        Object retVal = proceedingJoinPoint.proceed();

        /*
         * 连接点执行后代码块
         */
        return retVal;
    }

    /**
     *  <p>在连接点执行之前执行 这个方法不能阻止连接点执行<p>
     *  <p>带参数格式：@Before("aspect() && args(o)") 配合doBefore(JoinPoint joinPoint, * o) 匹配只有1个参数o切参数类型为*的方法</p>
     */
    @Before("aspect()")
    public void doBefore(JoinPoint joinPoint){}

    /**
     *<p> 在连接点执行之后执行（返回通知/异常之前）<p>
     */
    @After(value = "aspect()")
    public void doAfter(JoinPoint joinPoint){}


    /**
     * <p>在连接点执行之后执行<p>
     * <p>
     * 	也可以修改 Object 为对应的 Class 类型以执行返回类型为对应类型的数据 <br>
     * 	<font color="red">注意: 修改了 Class 类型之后 返回类型不是该 Class 类型的数据不会执行此方法</font>
     * </p>
     */
    @AfterReturning(pointcut = "aspect()", returning = "o")
    public void doAfterReturning(JoinPoint joinPoint, Object o){}


    /**
     * <p>在连接点抛出异常之后执行</p>
     */
    @AfterThrowing(pointcut = "aspect()", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, Exception e){}
}
